﻿using System;
using System.Collections.Generic;
using Ecng.Common;

namespace StockSharp.AlfaDirect
{
	/// <summary>
	/// Тайм-фреймы для исторических свечек Альфа-Директ.
	/// </summary>
	public sealed class AlfaTimeFrames
	{
		private static readonly Dictionary<Int32, AlfaTimeFrames> _intervals = new Dictionary<Int32, AlfaTimeFrames>();
		private static readonly Dictionary<TimeSpan, AlfaTimeFrames> _values = new Dictionary<TimeSpan, AlfaTimeFrames>();

		private readonly TimeSpan _value;

		static AlfaTimeFrames()
		{
			Minute1 = new AlfaTimeFrames(0, TimeSpan.FromTicks(TimeSpan.TicksPerMinute));
			Minute5 = new AlfaTimeFrames(1, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 5));
			Minute10 = new AlfaTimeFrames(2, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 10));
			Minute15 = new AlfaTimeFrames(3, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 15));
			Minute30 = new AlfaTimeFrames(4, TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 30));
			Hour = new AlfaTimeFrames(5, TimeSpan.FromTicks(TimeSpan.TicksPerHour));
			Day = new AlfaTimeFrames(6, TimeSpan.FromTicks(TimeSpan.TicksPerDay));
			Week = new AlfaTimeFrames(7, TimeSpan.FromTicks(TimeSpanHelper.TicksPerWeek));
			Month = new AlfaTimeFrames(8, TimeSpan.FromTicks(TimeSpanHelper.TicksPerMonth));
			Year = new AlfaTimeFrames(9, TimeSpan.FromTicks(TimeSpanHelper.TicksPerYear));
		}

		private AlfaTimeFrames(Int32 interval, TimeSpan value)
		{
			Interval = interval;

			_value = value;

			_intervals.Add(interval, this);
			_values.Add(value, this);
		}

		internal static AlfaTimeFrames GetTimeFrame(Int32 interval)
		{
			return _intervals[interval];
		}

		/// <summary>
		/// Минутный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Minute1 { get; private set; }

		/// <summary>
		/// Пяти минутный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Minute5 { get; private set; }

		/// <summary>
		/// Десяти минутный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Minute10 { get; private set; }

		/// <summary>
		/// Пятнадцати минутный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Minute15 { get; private set; }

		/// <summary>
		/// Тридцати минутный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Minute30 { get; private set; }

		/// <summary>
		/// Часовой тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Hour { get; private set; }

		/// <summary>
		/// Дневной тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Day { get; private set; }

		/// <summary>
		/// Недельный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Week { get; private set; }

		/// <summary>
		/// Месячный тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Month { get; private set; }

		/// <summary>
		/// Годовой тайм-фрейм.
		/// </summary>
		public static AlfaTimeFrames Year { get; private set; }

		internal Int32 Interval { get; private set; }

		/// <summary>
		/// Привести <see cref="TimeSpan"/> значение к объекту <see cref="AlfaTimeFrames"/>.
		/// </summary>
		/// <param name="value"><see cref="TimeSpan"/> значение.</param>
		/// <returns>Объект <see cref="AlfaTimeFrames"/>.</returns>
		public static implicit operator AlfaTimeFrames(TimeSpan value)
		{
			return _values[value];
		}

		/// <summary>
		/// Привести объект <see cref="AlfaTimeFrames"/> к <see cref="TimeSpan"/> значению.
		/// </summary>
		/// <param name="timeFrame">Объект <see cref="AlfaTimeFrames"/>.</param>
		/// <returns><see cref="TimeSpan"/> значение.</returns>
		public static explicit operator TimeSpan(AlfaTimeFrames timeFrame)
		{
			if (timeFrame == null)
				throw new ArgumentNullException("timeFrame");

			return timeFrame._value;
		}
	}
}